// Package dbsvc
// @Author: zhangdi
package dbsvc

import (
	"errors"
	"server/application/db/dbinit"
	"server/application/db/system/columns"
	"server/application/db/system/dbdto"
	"server/application/db/system/entity"
	"server/application/db/system/repository"
	"server/application/dto"
	"server/pkg/mylog"
	"server/pkg/utils"
	"server/pkg/where"
	"server/setting"
	"strings"
)

// SysRolePermissionsCreate 创建
func SysRolePermissionsCreate(dtoCreate *dbdto.SysRolePermissionsCreate) (*dbdto.SysRolePermissionsInfo, error) {
	return repository.Create[
		entity.SysRolePermissions, dbdto.SysRolePermissionsCreate, dbdto.SysRolePermissionsInfo,
	](dtoCreate)
}

// SysRolePermissionsCreateBatch 批量创建,返回插入记录的条数和error
func SysRolePermissionsCreateBatch(dtoCreateData []dbdto.SysRolePermissionsCreate, WhenErrorUpdate bool) (int64, error) {
	return repository.CreateBatch[
		entity.SysRolePermissions, dbdto.SysRolePermissionsCreate,
	](dtoCreateData, WhenErrorUpdate)
}

// SysRolePermissionsFindOne 查找
func SysRolePermissionsFindOne(wheres []*where.Condition) (*dbdto.SysRolePermissionsInfo, error) {
	return repository.FindOne[
		entity.SysRolePermissions, dbdto.SysRolePermissionsInfo,
	](wheres, false)
}

func SysRolePermissionsFindOneById(id uint) (*dbdto.SysRolePermissionsInfo, error) {
	wheres := where.FormatOne("id", "=", id)
	return repository.FindOne[
		entity.SysRolePermissions, dbdto.SysRolePermissionsInfo,
	](wheres, false)
}

// SysRolePermissionsFindList 查找列表
func SysRolePermissionsFindList(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysRolePermissionsInfo, error) {
	return repository.FindList[
		entity.SysRolePermissions, dbdto.SysRolePermissionsInfo](wheres, extra, false)
}

// SysRolePermissionsSearch 搜索
func SysRolePermissionsSearch(wheres []*where.Condition, extra *where.Extra) ([]*dbdto.SysRolePermissionsInfo, int64) {
	total, err := SysRolePermissionsGetTotal(wheres)
	list := make([]*dbdto.SysRolePermissionsInfo, 0)
	if err != nil || total <= 0 {
		return list, 0
	}
	list, err = SysRolePermissionsFindList(wheres, extra)
	return list, total
}

// SysRolePermissionsUpdate 更新，字段可按规则传入，传入那个修改哪个
func SysRolePermissionsUpdate(wheres []*where.Condition, dtoUpdate *dbdto.SysRolePermissionsUpdate, columnsCfg ...string) error {
	return repository.Update[
		entity.SysRolePermissions, dbdto.SysRolePermissionsUpdate](wheres, dtoUpdate, columnsCfg...)
}

// SysRolePermissionsDelete 删除（deleted_at存在则是软删除）
func SysRolePermissionsDelete(wheres []*where.Condition) error {
	return repository.Delete[entity.SysRolePermissions](wheres, setting.UseSoftDelete)
}

// SysRolePermissionsGetTotal 获取总数
func SysRolePermissionsGetTotal(wheres []*where.Condition) (int64, error) {
	return repository.GetTotal[entity.SysRolePermissions](wheres)
}

// SysRolePermissionSave 保存角色的权限
func SysRolePermissionSave(params *dto.RequestSysRolePermissionsSave) error {
	//开启事务
	tx := dbinit.GetDbInstance().Begin()

	//先删除当前角色的原来的
	err := SysRolePermissionsDelete(where.FormatOne(columns.SysRolePermissionsRoleId, "=", params.RoleId))
	if err != nil {
		tx.Rollback() //回滚
		return errors.New("删除原因数据失败：" + err.Error())
	}

	//开始插入
	permissionSavelist := make([]dbdto.SysRolePermissionsCreate, 0)
	for i := 0; i < len(params.PermissionNames); i++ {
		permissionName := params.PermissionNames[i]
		if strings.Contains(permissionName, ".") {
			//如果name包含点说明是权限，如User.create,否则是菜单
			item := dbdto.SysRolePermissionsCreate{
				RoleId:    params.RoleId,
				CreatorId: params.CreatorId,
				//全选名
				PermissionName: strings.Split(permissionName, ".")[1],
				//菜单name
				MenuName:           strings.Split(permissionName, ".")[0],
				PermissionFullName: permissionName, //完整权限名称
			}

			permissionSavelist = append(permissionSavelist, item)
		}

	}
	insertNum, err := SysRolePermissionsCreateBatch(permissionSavelist, false)
	if err != nil {
		tx.Rollback() //回滚
		return errors.New("保存失败：" + err.Error())
	}

	if int(insertNum) != len(permissionSavelist) {
		tx.Rollback() //如果条数不一致，一样回滚
		return errors.New("插入条数值不一致，数据回滚：" + err.Error())
	}
	tx.Commit() //提交事务

	return nil
}

// SysRolePermissionNamesByUserId 根据用户ID获取他的所有权限
func SysRolePermissionNamesByUserId(userid uint) []string {
	roleIds := SysUserGetRoleIds(userid)
	return SysRolePermissionGetFullName(roleIds...)
}

// SysRolePermissionGetAllFullNames 获取所有的菜单权限列表
func SysRolePermissionGetAllFullNames() []string {
	allMenu, err := SysMenuFindList(where.Format(), nil)
	permissionNames := make([]string, 0)
	if err != nil {
		mylog.Error("SysRolePermissionGetAllFullNames()" + err.Error())
		return permissionNames
	}
	if allMenu != nil && len(allMenu) > 0 {
		for _, menu := range allMenu {
			menuPermissionStr := menu.Permissions
			menuPermissionArr := strings.Split(menuPermissionStr, ",")
			for _, permissionName := range menuPermissionArr {
				permissionNames = append(permissionNames, menu.Name+"."+permissionName)
			}
		}
	}
	return permissionNames
}

// SysRolePermissionGetFullName 获取多个角色的权限列表的fullName(并集)
func SysRolePermissionGetFullName(roleIds ...uint) []string {
	PermissionList := make([]string, 0)
	//1.从数据库获取权限列表
	for _, roleId := range roleIds {
		wheres := where.Format(where.Opt(columns.SysRolePermissionsRoleId, "=", roleId))
		list, err := SysRolePermissionsFindList(wheres, nil)
		if err != nil {
			continue
		}
		if list != nil && len(list) > 0 {
			for _, permissionInfo := range list {
				//如果权限列表没有存在该权限，则插入
				if !utils.ArrContains(PermissionList, permissionInfo.PermissionFullName) {
					PermissionList = append(PermissionList, permissionInfo.PermissionFullName)
				}
			}
		}
	}
	return PermissionList
}

// SysRolePermissionGetAuthButton 获取角色的按钮权限列表
func SysRolePermissionGetAuthButton(userId uint, roleIds ...uint) map[string][]string {
	authButtons := make(map[string][]string, 0)
	permissionFullNameList := make([]string, 0)
	if SysUserIsSuperAdmin(userId) { //超级管理员，获取所有的按钮权限
		permissionFullNameList = SysRolePermissionGetAllFullNames()
	} else { //非超级管理员 从数据库表获取所有的菜单权限
		permissionFullNameList = SysRolePermissionGetFullName(roleIds...)
	}

	for _, fullName := range permissionFullNameList {
		if strings.Contains(fullName, ".") {
			nameArr := strings.Split(fullName, ".")
			if len(nameArr) != 2 {
				continue
			}
			k := nameArr[0]
			permissionName := nameArr[1]

			// 检查 k 是否已经存在于 authButtons
			if _, ok := authButtons[k]; ok {
				// k 已存在，将 permissionName 追加到切片中
				authButtons[k] = append(authButtons[k], permissionName)
			} else {
				// k 不存在，创建新的切片并添加 permissionName
				authButtons[k] = []string{permissionName}
			}
		}
	}
	return authButtons
}
